package rollercoaster.train;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.media.opengl.GL2ES2;

import rollercoaster.commons.Material;
import rollercoaster.commons.Model;
import rollercoaster.commons.Node;
import rollercoaster.commons.Vertex3D;
import rollercoaster.commons.interfaces.NodoProducer;
import rollercoaster.commons.interfaces.Surface3D;
import rollercoaster.commons.interfaces.SurfaceTessellationAlgorithm;
import rollercoaster.environment.interfaces.IModelReader;
import rollercoaster.environment.utils.ModelMaker;
import rollercoaster.train.interfaces.IMultipleSurfaceControlPointsReader;
import rollercoaster.train.interfaces.VagoneDataReader;

public class ClassicCoachProducer implements NodoProducer {

	private VagoneDataReader textureReader;
	private IMultipleSurfaceControlPointsReader vertexReader;
	private SurfaceTessellationAlgorithm tess;
	
	public ClassicCoachProducer(VagoneDataReader textureReader,
			IMultipleSurfaceControlPointsReader vertexReader,
			SurfaceTessellationAlgorithm tess) {
		super();
		this.textureReader = textureReader;
		this.vertexReader = vertexReader;
		this.tess = tess;
	}

	public Node getNode(GL2ES2 gl) {
		
		List<Model> models=new ArrayList<Model>();
		
		HashMap<String, List<String>> textures=textureReader.getTextureInfo();
		
		float[] texMatrix={
				1.0f,0,
				0,1.0f
		};
		
		
		for (Map.Entry<String, List<String>> entry : textures.entrySet()) {
			Material mat=new Material(entry.getKey());
			mat.init(gl);
			mat.setTransformMatrix(texMatrix);
			
			List<String> valueList=entry.getValue(); //per ogni obj associato al materiale mat
			for (String val : valueList) {
				List<Surface3D> surfaces=new ArrayList<Surface3D>();
				Vertex3D[][] controlPoints;
				Surface3D surf;
				List<Vertex3D[][]> controlPointsList=vertexReader.getControlPointsList(val);
				int numSurfaces=controlPointsList.size();
				
				for (int i = 0; i < numSurfaces; i++) {
					controlPoints=controlPointsList.get(i);
					surf=new UniformOpenSecondOrderPatch(controlPoints);
					surfaces.add(surf);
					
				}
				
				IModelReader mr=tess.tessellate(surfaces.get(0));
				ModelMaker maker=new ModelMaker(mr);
				
				for (int i = 0; i < numSurfaces; i++) {
					if(i!=0){
						mr=tess.tessellate(surfaces.get(i));
						maker.setModelReader(mr);
					}
					Model model=maker.makeModel();
					model.initBuffers(gl);
					model.setMaterial(mat);
					models.add(model);
				}
				
				
				
			}
			
		}
		
		
		return new Node(models);
	}

}
